package com.qunar.qcf.socket.nio;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.DatagramChannel;

import com.qunar.qcf.core.buffer.IoBuffer;
import com.qunar.qcf.core.service.DefaultTransportMetadata;
import com.qunar.qcf.core.service.IoProcessor;
import com.qunar.qcf.core.service.IoService;
import com.qunar.qcf.core.service.TransportMetadata;
import com.qunar.qcf.core.session.IoSession;
import com.qunar.qcf.socket.DatagramSessionConfig;

/**
 * An {@link IoSession} for datagram transport (UDP/IP).
 *
 */
class NioDatagramSession extends NioSession {
    static final TransportMetadata METADATA = new DefaultTransportMetadata("nio", "datagram", true, false,
            InetSocketAddress.class, DatagramSessionConfig.class, IoBuffer.class);

    private final InetSocketAddress localAddress;

    private final InetSocketAddress remoteAddress;

    /**
     * Creates a new acceptor-side session instance.
     */
    NioDatagramSession(IoService service, DatagramChannel channel, IoProcessor<NioSession> processor,
            SocketAddress remoteAddress) {
        super(processor, service, channel);
        config = new NioDatagramSessionConfig(channel);
        config.setAll(service.getSessionConfig());
        this.remoteAddress = (InetSocketAddress) remoteAddress;
        this.localAddress = (InetSocketAddress) channel.socket().getLocalSocketAddress();
    }

    /**
     * Creates a new connector-side session instance.
     */
    NioDatagramSession(IoService service, DatagramChannel channel, IoProcessor<NioSession> processor) {
        this(service, channel, processor, channel.socket().getRemoteSocketAddress());
    }

    /**
     * {@inheritDoc}
     */
    public DatagramSessionConfig getConfig() {
        return (DatagramSessionConfig) config;
    }

    @Override
    DatagramChannel getChannel() {
        return (DatagramChannel) channel;
    }

    public TransportMetadata getTransportMetadata() {
        return METADATA;
    }

    public InetSocketAddress getRemoteAddress() {
        return remoteAddress;
    }

    public InetSocketAddress getLocalAddress() {
        return localAddress;
    }

    @Override
    public InetSocketAddress getServiceAddress() {
        return (InetSocketAddress) super.getServiceAddress();
    }
}